
using System.Collections.Generic;
using System.Linq;
using RimWorld;
using Verse;
using Verse.AI;

namespace RimZombieGirl
{
    // JobGiver_Zombie_GetFood：专为僵尸或特定生物设计的进食行为提供者，继承自ThinkNode_JobGiver
    // 用于在AI决策树中决定是否生成“获取食物”任务
    // 参考了RimWorld的JobGiver_GetFood逻辑，但进行了定制以适应僵尸特性
    public class JobGiver_Zombie_GetFood : ThinkNode_JobGiver
    {
        // 最低触发饥饿等级（例如：仅当饥饿达到“饥饿”或更严重时才执行）
        private HungerCategory minCategory;

        // 食物当前水平百分比上限，超过此值则不触发进食（避免饱腹时仍找食物）
        private float maxLevelPercentage = 1f;

        // 是否强制在整个地图范围内扫描食物源（无视常规区域限制）
        public bool forceScanWholeMap;

        // 深拷贝方法：确保在复制ThinkNode时所有自定义字段也被正确复制
        // 引用RimWorld源码中ThinkNode.DeepCopy模式（类似JobGiver_Wander）
        public override ThinkNode DeepCopy(bool resolve = true)
        {
            JobGiver_Zombie_GetFood obj = (JobGiver_Zombie_GetFood)base.DeepCopy(resolve);
            obj.minCategory = minCategory;
            obj.maxLevelPercentage = maxLevelPercentage;
            obj.forceScanWholeMap = forceScanWholeMap;
            return obj;
        }

        // 获取该Job的优先级，决定AI是否选择此行为
        // 优先级越高，越可能被选中执行
        public override float GetPriority(Pawn pawn)
        {
            Need_Food food = pawn.needs.food;
            if (food == null)
            {
                return 0f; // 无食物需求，不执行
            }

            // 若为虚弱状态（CurCategory < 3）且需要他人喂食（如婴儿、瘫痪者），则不自行觅食
            if ((int)pawn.needs.food.CurCategory < 3 && FoodUtility.ShouldBeFedBySomeone(pawn))
            {
                return 0f;
            }

            // 当前饥饿等级低于设定的最低触发等级，不执行
            if ((int)food.CurCategory < (int)minCategory)
            {
                return 0f;
            }

            // 当前食物水平高于允许的最大百分比，不执行
            if (food.CurLevelPercentage > maxLevelPercentage)
            {
                return 0f;
            }

            // 如果当前食物水平低于种族期望进食阈值，则返回高优先级（9.5）
            if (food.CurLevelPercentage < pawn.RaceProps.FoodLevelPercentageWantEat)
            {
                return 9.5f;
            }

            return 0f;
        }

        // 尝试为指定Pawn生成一个“获取食物”的Job
        protected override Job TryGiveJob(Pawn pawn)
        {
            // Need_Zombie_DrinkBlood foodNeed = pawn.needs.TryGetNeed<Need_Zombie_DrinkBlood>();
            // // 若无食物需求、饥饿等级不足、或已过饱，则不生成任务
            // if (foodNeed == null || (int)foodNeed.CurCategory < (int)minCategory || foodNeed.CurLevelPercentage > maxLevelPercentage)
            // {
            //     return null;
            // }

            // FoodPreferability foodPreferability = FoodPreferability.Undefined; // 食物偏好
            // bool allowCorpse = false; // 是否允许食用尸体

            // if (pawn.AnimalOrWildMan())
            // {
            //     allowCorpse = true;
            // }
            // else if (foodNeed.VeryStarving)
            // {
            //     // 极度饥饿状态：允许食用尸体
            //     allowCorpse = true;
            //     foodPreferability = FoodPreferability.DesperateOnly; // 设置食物偏好为“仅在绝望时”
            // }
            // bool desperate = pawn.needs.food.CurCategory == HungerCategory.Starving; // 是否处于饥饿/濒死状态
            // FoodPreferability minPrefOverride = foodPreferability; // 食物偏好最低要求

            // // 尝试为Pawn找到最佳食物来源
            // // 参数说明：
            // // canRefillDispenser: 允许补充营养膏机
            // // canUseInventory: 可使用自己背包
            // // allowForbidden: 不允许使用被禁止的物品
            // // calculateWantedStackCount: 不计算堆叠数量（因后续手动设置）
            // if (!FoodUtility.TryFindBestFoodSourceFor(pawn, pawn, desperate, out var foodSource, out var foodDef, canRefillDispenser: true, canUseInventory: true, canUsePackAnimalInventory: true, allowForbidden: false, allowCorpse, allowSociallyImproper: false, pawn.IsWildMan(), forceScanWholeMap, ignoreReservations: false, calculateWantedStackCount: false, allowVenerated: false, minPrefOverride))
            // {
            //     // 若未找到食物源，且启用了Odyssey模组且该种族可捕鱼，则尝试生成捕鱼任务
            //     if (ModsConfig.OdysseyActive && pawn.RaceProps.canFishForFood)
            //     {
            //         return TryFindFishJob(pawn);
            //     }

            //     return null;
            // }

            // // 若食物源为另一个Pawn（如猎物），生成捕食任务
            // if (foodSource is Pawn pawn2)
            // {
            //     Job job = JobMaker.MakeJob(JobDefOf.PredatorHunt, pawn2);
            //     job.killIncappedTarget = true; // 允许击杀已倒下的目标
            //     return job;
            // }

            // // 若食物源为植物且可收获，则生成收获任务
            // // if (foodSource is Plant && foodSource.def.plant.harvestedThingDef == foodDef)
            // // {
            // //     return JobMaker.MakeJob(JobDefOf.Harvest, foodSource);
            // // }

            // // 若食物源为营养膏机但原料不足，尝试从邻近漏斗补充
            // if (foodSource is Building_NutrientPasteDispenser building_NutrientPasteDispenser && !building_NutrientPasteDispenser.HasEnoughFeedstockInHoppers())
            // {
            //     Building building = building_NutrientPasteDispenser.AdjacentReachableHopper(pawn);
            //     if (building != null)
            //     {
            //         ISlotGroupParent hopperSgp = building as ISlotGroupParent;
            //         Job job2 = WorkGiver_CookFillHopper.HopperFillFoodJob(pawn, hopperSgp, forced: false);
            //         if (job2 != null)
            //         {
            //             return job2;
            //         }
            //     }

            //     // 若无法补充，则重新搜索其他可用食物源（排除空/满的分配器）
            //     foodSource = FoodUtility.BestFoodSourceOnMap(pawn, pawn, desperate, out foodDef, FoodPreferability.MealLavish, allowPlant: false, !pawn.IsTeetotaler(), allowCorpse: false, allowDispenserFull: false, allowDispenserEmpty: false, allowForbidden: false, allowSociallyImproper: false, allowHarvest: false, forceScanWholeMap);
            //     if (foodSource == null)
            //     {
            //         return null;
            //     }
            // }

            // // 计算该食物能提供的营养值
            // float nutrition = FoodUtility.GetNutrition(pawn, foodSource, foodDef);

            // // 检查食物是否属于其他Pawn的背包
            // Pawn pawn3 = (foodSource.ParentHolder as Pawn_InventoryTracker)?.pawn;
            // if (pawn3 != null && pawn3 != pawn)
            // {
            //     // 生成从他人背包取物的任务
            //     Job job3 = JobMaker.MakeJob(JobDefOf.TakeFromOtherInventory, foodSource, pawn3);
            //     job3.count = FoodUtility.WillIngestStackCountOf(pawn, foodDef, nutrition); // 设置摄入数量
            //     return job3;
            // }

            // // 默认情况：生成直接进食任务
            // // TODO 额外修改，新鲜的尸体或者鲜肉是否产生更多的营养
            // Job job4 = JobMaker.MakeJob(JobDefOf.Ingest, foodSource);
            // job4.count = FoodUtility.WillIngestStackCountOf(pawn, foodDef, nutrition); // 设置摄入数量
            // return job4;

            return null;
        }

        // 尝试为可捕鱼的Pawn生成捕鱼任务（仅在启用了Odyssey模组时调用）
        public static Job TryFindFishJob(Pawn pawn)
        {
            Map map = pawn.MapHeld;
            if (map != null)
            {
                WaterBodyTracker waterBodyTracker = map.waterBodyTracker;
                if (waterBodyTracker != null)
                {
                    // 若地图上没有任何含鱼水域，则无法捕鱼
                    if (!waterBodyTracker.AnyBodyContainsFish)
                    {
                        return null;
                    }

                    // 筛选出有鱼且种群数量大于10的水域
                    List<WaterBody> validBodies = waterBodyTracker.Bodies.Where((WaterBody waterBody) => !waterBody.CommonFish.EnumerableNullOrEmpty() && waterBody.Population > 10f).ToList();
                    if (validBodies.Count == 0)
                    {
                        return null;
                    }

                    TraverseParms traverseParams = TraverseParms.For(pawn); // 获取Pawn通行参数
                    Region foundRegion = null;
                    WaterBody foundBody = null;

                    // 使用广度优先搜索寻找可达的含鱼水域区域
                    RegionTraverser.BreadthFirstTraverse(pawn.PositionHeld, map, (Region from, Region to) => to.Allows(traverseParams, isDestination: false), delegate (Region r)
                    {
                        foreach (WaterBody validBody in validBodies)
                        {
                            // 判断区域是否与水域边界重叠且至少有一个格子属于该水域
                            if (r.extentsClose.Overlaps(validBody.Bounds) && r.Cells.Any((IntVec3 c) => validBody.cells.Contains(c)))
                            {
                                foundRegion = r;
                                foundBody = validBody;
                                return true; // 找到后停止遍历
                            }
                        }

                        return false;
                    });
                    if (foundRegion == null)
                    {
                        return null;
                    }

                    // 获取该区域内所有可站立且属于该水域的格子
                    List<IntVec3> source = foundRegion.Cells.Where((IntVec3 c) => c.Standable(map) && c.InBounds(map) && c.GetWaterBody(map) == foundBody).ToList();
                    for (int num = 0; num < 30; num++)
                    {
                        IntVec3 intVec = source.RandomElement();
                        if (intVec.IsValid && intVec.Standable(map))
                        {
                            // 寻找最佳钓鱼站立点（通常在水边）
                            IntVec3 intVec2 = WorkGiver_Fish.BestStandSpotFor(pawn, intVec);
                            if (intVec2.IsValid)
                            {
                                // 生成钓鱼任务：目标为水域格子，站立点为岸边
                                return JobMaker.MakeJob(JobDefOf.FishAnimal, intVec, intVec2);
                            }
                        }
                    }

                    return null;
                }
            }

            return null;
        }
    }

}